package com.zhy.generator.codegen.mybatis.javacontroller.elements;

import com.zhy.generator.codegen.dom.java.*;
import com.zhy.generator.codegen.mybatis.AbstractGenerator;
import com.zhy.generator.codegen.mybatis.javacontroller.JavaControllerMethodConstant;
import com.zhy.generator.codegen.mybatis.javarequest.RequestInnerClassConstant;

import java.util.ArrayList;
import java.util.List;

import static com.zhy.generator.codegen.util.JavaBeansUtil.getCamelCaseString;


/**
 * @author 源
 */
public abstract class AbstractJavaControllerMethodGenerator extends AbstractGenerator {

    public abstract void addControllerElements(TopLevelClass tlc);

    public abstract String getMethodStr();

    protected FullyQualifiedJavaType getReturnType() {
        return new FullyQualifiedJavaType(JavaControllerMethodConstant.RESULT_RESPONSE);
    }

    protected  String getServiceShortName(){
        FullyQualifiedJavaType serviceType = new FullyQualifiedJavaType(introspectedTable.getServiceType());
        return getCamelCaseString(serviceType.getShortName(),false);
    }
    /**
     * controller 方法添加注解
     * @param tlc
     * @param listMethod
     */
    protected void addMethodAnnotations(TopLevelClass tlc, Method listMethod) {
        String annotation, value, desc, method;
        switch (getMethodStr()) {
            case JavaControllerMethodConstant.LIST_METHOD:
                annotation = JavaControllerMethodConstant.LIST_METHOD_ANNOTATION;
                value = JavaControllerMethodConstant.LIST_METHOD_MAPPING;
                desc = JavaControllerMethodConstant.LIST_METHOD_desc;
                method = JavaControllerMethodConstant.LIST_METHOD_HTTPMETHOD;
                break;
            case JavaControllerMethodConstant.GET_METHOD:
                annotation = JavaControllerMethodConstant.GET_METHOD_ANNOTATION;
                value = JavaControllerMethodConstant.GET_METHOD_MAPPING;
                desc = JavaControllerMethodConstant.GET_METHOD_desc;
                method = JavaControllerMethodConstant.GET_METHOD_HTTPMETHOD;
                break;
            case JavaControllerMethodConstant.ADD_METHOD:
                annotation = JavaControllerMethodConstant.ADD_METHOD_ANNOTATION;
                value = JavaControllerMethodConstant.ADD_METHOD_MAPPING;
                desc = JavaControllerMethodConstant.ADD_METHOD_desc;
                method = JavaControllerMethodConstant.ADD_METHOD_HTTPMETHOD;
                break;
            case JavaControllerMethodConstant.EDIT_METHOD:
                annotation = JavaControllerMethodConstant.EDIT_METHOD_ANNOTATION;
                value = JavaControllerMethodConstant.EDIT_METHOD_MAPPING;
                desc = JavaControllerMethodConstant.EDIT_METHOD_desc;
                method = JavaControllerMethodConstant.EDIT_METHOD_HTTPMETHOD;
                break;
            case JavaControllerMethodConstant.DEL_METHOD:
                annotation = JavaControllerMethodConstant.DEL_METHOD_ANNOTATION;
                value = JavaControllerMethodConstant.DEL_METHOD_MAPPING;
                desc = JavaControllerMethodConstant.DEL_METHOD_desc;
                method = JavaControllerMethodConstant.DEL_METHOD_HTTPMETHOD;
                break;
            default:
                annotation = JavaControllerMethodConstant.LIST_METHOD_ANNOTATION;
                value = JavaControllerMethodConstant.LIST_METHOD_MAPPING;
                desc = JavaControllerMethodConstant.LIST_METHOD_desc;
                method = JavaControllerMethodConstant.LIST_METHOD_HTTPMETHOD;
                break;
        }

        StringBuffer mappingSB = new StringBuffer();
        mappingSB.append(annotation).append("(value=").append("\"").append(value).append("\"");
        if ("POST".equals(method)) {
            mappingSB.append(",consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE");
            tlc.addImportedType("org.springframework.web.bind.annotation.PostMapping");
        }else{
            tlc.addImportedType("org.springframework.web.bind.annotation.GetMapping");
        }
        mappingSB.append(")");
        listMethod.addAnnotation(mappingSB.toString());
        listMethod.addAnnotation("@ApiOperation(value = \"" + desc + "\", httpMethod = \"" + method + "\")");

        tlc.addImportedType("org.springframework.http.MediaType");
        tlc.addImportedType("io.swagger.annotations.ApiOperation");

    }

    /**
     * 添加参数列表
     * @param tlc
     * @param method
     */
    protected void addParameter(TopLevelClass tlc, Method method) {
        String requestTypeStr = introspectedTable.getRequestType();
        StringBuffer sb = new StringBuffer(requestTypeStr);

        List<String> annotations = new ArrayList<>();
        List<String> annotationsImpTypes = new ArrayList<>();

        annotations.add("@Validated");
        annotationsImpTypes.add("org.springframework.validation.annotation.Validated");
        String methodStr = getMethodStr();
        switch (methodStr) {
            case JavaControllerMethodConstant.LIST_METHOD:
                sb.append(".").append(RequestInnerClassConstant.LIST_PARAM);
                break;
            case JavaControllerMethodConstant.GET_METHOD:
                sb.append(".").append(RequestInnerClassConstant.PK_PARAM);
                break;
            case JavaControllerMethodConstant.ADD_METHOD:
                sb.append(".").append(RequestInnerClassConstant.ADD_PARAM);
                annotations.add("@RequestBody");
                annotationsImpTypes.add("org.springframework.web.bind.annotation.RequestBody");
                break;
            case JavaControllerMethodConstant.EDIT_METHOD:
                sb.append(".").append(RequestInnerClassConstant.EDIT_PARAM);
                annotations.add("@RequestBody");
                annotationsImpTypes.add("org.springframework.web.bind.annotation.RequestBody");
                break;
            case JavaControllerMethodConstant.DEL_METHOD:
                sb.append(".").append(RequestInnerClassConstant.PK_PARAM);
                break;
            default:
                sb.append(".").append(RequestInnerClassConstant.PK_PARAM);
                break;
        }

        FullyQualifiedJavaType paramType = new FullyQualifiedJavaType(sb.toString());
        TopLevelClass c = new TopLevelClass(paramType);
        List<Field> fields = c.getFields();
        List<Method> methods = c.getMethods();
        Parameter p = new Parameter(paramType, "param");
        for (String annotation : annotations) {
            p.addAnnotation(annotation);
        }
        method.addParameter(p);
        tlc.addImportedType(paramType);

        for (String annotationsImpType : annotationsImpTypes) {
            tlc.addImportedType(annotationsImpType);
        }
    }
}
